package com.ess.common.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.ClassUtils;

public class ClassUtil
{
    public static class Param
    {
        public String name;
        public Class<?> type;

        public Param(String name, Class<?> type)
        {
            this.name = name;
            this.type = type;
        }
    }

    public static List<Param> getMethodParams(Method method)
    {
        List<Param> ret = new ArrayList<Param>();
        Parameter[] paras = method.getParameters();
        for (int i = 0; i < paras.length; i++)
        {
            ret.add(new Param(paras[i].getName(), paras[i].getType()));
        }
        return ret;
    }

    public static String searchParams(Method method, Object[] args) 
    {
        StringBuilder sb = new StringBuilder();
        Parameter[] paras = method.getParameters();
        for (int i = 0; i < paras.length; i++)
        {
            try
            {
                sb.append(searchParams("", paras[i].getName(), args[i]));
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        return sb.length() == 0 ? "" : sb.substring(1);
    }

    private static String searchParams(String prefix, String name, Object obj) throws Exception
    {
        if (obj == null)
        {
            return "";
        }
        else if (isPrimitive(obj))
        {
            return "&" + prefix + name + "=" + obj;
        }
        else
        {
            StringBuilder sb = new StringBuilder();
            for (Field f : obj.getClass().getDeclaredFields())
            {
                f.setAccessible(true);
                Object val = f.get(obj);
                if (val != null)
                {
                    sb.append(searchParams(isPrimitive(val) ? prefix : (prefix + name + "."), f.getName(), val));
                }
            }
            return sb.toString();
        }
    }

    private static boolean isPrimitive(Object obj)
    {
        return obj.getClass() == String.class || ClassUtils.isPrimitiveOrWrapper(obj.getClass());
    }
}
